use casbin::function_map::key_match2;
use casbin::{CoreApi, DefaultModel};
use std::sync::Arc;
use tokio::sync::RwLock;
use casbin::Enforcer;

use sqlx_adapter::SqlxAdapter;
use std::sync::OnceLock;


pub type SharedEnforcer = Arc<RwLock<Enforcer>>;

// 全局静态变量
static ENFORCER: OnceLock<SharedEnforcer> = OnceLock::new();


/// 1️⃣ 创建 / 初始化 Enforcer（建表 + 载入模型）
pub async fn create_enforcer() -> SharedEnforcer {
    println!("rbac init ...");
    let adapter = SqlxAdapter::new("sqlite://./policy.db", 1)
        .await
        .expect("sqlite adapter");

    let model = DefaultModel::from_file("rbac_with_pattern_model.conf")
        .await
        .expect("model file");

    let enforcer = Enforcer::new(model, adapter)
        .await
        .expect("enforcer");

    // 启用通配符
    enforcer
        .get_role_manager()
        .write()
        .matching_fn(Some(key_match2), None);

    // 放入全局
    let _ = ENFORCER
        .set(Arc::new(RwLock::new(enforcer)));
    println!("rbac init ok");

    ENFORCER.get().unwrap().clone()
}



/// 任何地方都可以调用，返回全局 &'static Arc<RwLock<Enforcer>>
pub fn enforcer() -> &'static SharedEnforcer {
    ENFORCER.get().expect("enforcer not initialized")
}

//pub async fn add_policy(sub: &str, obj: &str, act: &str) -> casbin::Result<bool> {
//    enforcer().write().await.add_policy(vec![sub, obj, act]).await
//}

//pub async fn remove_policy(sub: &str, obj: &str, act: &str) -> casbin::Result<bool> {
//    enforcer().write().await.remove_policy(vec![sub, obj, act]).await
//}



    // 2. 任何地方都能直接使用
    // FIXME: add policy from API invoking.
//    policy::add_policy("alice", "/orders", "GET").await?;
//    policy::add_role_for_user("alice", "admin").await?;

//    println!("policy added");
